//
//  YPPasswordGenerator.swift
//  YourPassword
//
//  Created by 李冲 on 15/11/23.
//  Copyright © 2015年 Saye. All rights reserved.
//

import UIKit

struct YPPasswordSet : OptionSetType {
    let rawValue: Int
    init(rawValue: Int) { self.rawValue = rawValue }
    
    static let Number                       = YPPasswordSet(rawValue: 1 << 0)
    static let Character                    = YPPasswordSet(rawValue: 1 << 1)
    static let SpecificSymbol               = YPPasswordSet(rawValue: 1 << 2)
    static let NumberAndChar: YPPasswordSet = [Number, Character]
    static let All: YPPasswordSet           = [Number, Character, SpecificSymbol]
}

let YPNumberSet: [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let YPCharacterSet: [Character] = ["a", "b", "c", "d", "e", "f", "g", "h", "i",
                                    "j", "k", "l", "m", "n", "o", "p", "q", "r",
                                    "s", "t", "u", "v", "w", "x", "y", "z",
                                    "A", "B", "C", "D", "E", "F", "G", "H", "I",
                                    "J", "K", "L", "M", "N", "O", "P", "Q", "R",
                                    "S", "T", "U", "V", "W", "X", "Y", "Z"]
let YPSepcificSymbolSet: [Character] = ["!", "@", "#", "$", "%", "&"]

class YPPasswordConfig : NSObject {
    var length: Int = 10
    var passwordSet: YPPasswordSet = YPPasswordSet.NumberAndChar
    override init() {
        
    }
    init(dictionary: NSDictionary) {
        if let length = dictionary["length"] as? Int {
            self.length = length
        }
        else {
            self.length = 10
        }
        
        if let passwordSet = dictionary["passwordSet"] as? Int {
            self.passwordSet = YPPasswordSet.init(rawValue: passwordSet)
        }
    }
    func dictionary() -> NSDictionary {
        return ["length" : length, "passwordSet" : passwordSet.rawValue]
    }
}


class YPPasswordGenerator {
    var config: YPPasswordConfig
    init() {
        self.config = YPPasswordConfig()
    }
    init(config: YPPasswordConfig) {
        self.config = config
    }
    
    func generatePassword(secret: String, withKeyword keyword: String) -> String? {
        if let first = YPCrypto.SHA256(secret) {
            if let second = YPCrypto.SHA256(keyword) {
                var offset = 0
                var position = 0
                var result = ""
                let passwordSet = self.passwordSet()
                for (var i = 0; i < config.length; i++) {
                    if position >= first.count {
                        position = position % first.count
                        offset++
                    }
                    let secondPos = (offset + position) % second.count
                    let number = first[position] ^ second[secondPos]
                    result.append(passwordSet[Int(number) % passwordSet.count])
                    position++
                }
                return result
            }
        }
        return nil
    }
    
    func passwordSet() -> [Character] {
        var passwordSet = [Character]()
        if config.passwordSet.contains(.Number) {
            passwordSet += YPNumberSet
        }
        if config.passwordSet.contains(.Character) {
            passwordSet += YPCharacterSet
        }
        if config.passwordSet.contains(.SpecificSymbol) {
            passwordSet += YPSepcificSymbolSet
        }
        return passwordSet
    }
}
